<script setup lang="ts">
import { computed, nextTick, onBeforeMount, reactive, ref, unref } from 'vue'
import { useBaseApi } from '@/api/base'
import { useRoute } from 'vue-router'
import { ArrowDown, Close, Search, Stamp, List } from '@element-plus/icons-vue'
import type { VxeGridInstance, VxeToolbarProps } from 'vxe-table'
import type {
  BusinessUIAction,
  BusinessUIFormType,
  BusinessUIQueryType,
  BusinessUITableType,
  DicType,
  WorkflowDesignRow
} from '@/types/custom'
import { useWfApi } from '@/api/wf'
import { getNotEmpty } from '@/utils/custom'
import emitter from '@/utils/mitt'

import TemplateVxeGrid from '@/views/components/grid/components/TemplateVxeGrid.vue'
import NeedViewStamp from '@/views/system/flow/component/NeedViewStamp.vue'
import { ElMessage } from 'element-plus'

interface Props {
  disabled?: boolean
  insert?: boolean
  boxShadow?: boolean
}

const route = useRoute()

const props = defineProps<Props>()

const emit = defineEmits(['fetch', 'close'])

const modelValue = defineModel<string>()

const { get_business_ui } = useBaseApi()
const { GetUserAppGroup } = useWfApi()

// 加载
const loading = ref(false)
// 查询栏
const uiQuery = ref<BusinessUIQueryType | undefined>()
// 表格
const uiTable = ref<BusinessUITableType | undefined>()
// 表单
const uiForm = ref<BusinessUIFormType | undefined>()
// 表单字典
const dicTable = ref<DicType[]>([])
// 查询字典
const dicQuery = ref<DicType[]>([])
// 薪酬按钮配置
const uiActions = ref<BusinessUIAction[]>([])
// 关联流程
const wfDesign = ref<WorkflowDesignRow | undefined>()
// 表格
const gridRef = ref<InstanceType<typeof TemplateVxeGrid>>()
// 批量审批
const stampRef = ref<InstanceType<typeof NeedViewStamp>>()
// 工具栏配置
const toolbarConfig = ref<VxeToolbarProps>({})
// 查询栏
const state = reactive({
  page: 1,
  pageSize: 20,
  query_type: '0',
  ins_name: ''
})
const insItems = ref<SelectOptionType[]>([])

// /**
//  * 初始化mitt事件
//  */
// const onEventMitt = () => {
//   if (uiTable.value && ['sys_workflow_list', 'sys_user_msg'].includes(uiTable.value.id)) {
//     mittBus.on('onUpdateMsg', () => {
//       onFetch()
//     })
//   }
// }

/**
 * 格式化默认参数
 */
const onDefaultFetch = async () => {
  const id = unref(modelValue)
  if (!id) return
  loading.value = true
  await get_business_ui(id, true)
    .then(({ data }) => {
      const dic_table = data.dic_table || []
      const dic_query = data.dic_query || []
      const ui_table = data.ui_table
      const ui_query = data.ui_query
      const ui_form = data.ui_form
      const ui_actions = props.disabled ? [] : data.actions || []
      const wf_design = data.wf_design
      if (ui_table) uiTable.value = ui_table
      if (ui_query) uiQuery.value = ui_query
      if (ui_form) uiForm.value = ui_form

      dicQuery.value = dic_query
      dicTable.value = dic_table
      wfDesign.value = wf_design
      uiActions.value = ui_actions
      nextTick(onFetch)
    })
    .finally(() => (loading.value = false))
}

const onFetch = () => {
  loading.value = true
  if (gridRef.value) {
    gridRef.value.onFetch(state).finally(() => {
      loading.value = false
    })
  } else {
    loading.value = false
  }
}

const onGridReady = () => {
  loading.value = false
  GetUserAppGroup<{ count: number; ins_name: string; ins_title: string }[]>().then(({ data }) => {
    insItems.value = data.map((v) => {
      return {
        label: v.ins_title,
        value: v.ins_name,
        count: v.count
      }
    })
  })
}

onBeforeMount(() => {
  if (route.query.id) {
    modelValue.value = String(route.query.id)
  } else if (!modelValue.value) modelValue.value = 'sys_workflow_list'
  onDefaultFetch()
})

defineExpose({ onFetch })

const getInsItemsName = computed(() => {
  const item = insItems.value.find((f) => f.value === state.ins_name)
  return item ? item.label : ''
})

const getInsItemsCount = computed(() => {
  const item = insItems.value.find((f) => f.value === state.ins_name)
  return item ? item.count : 0
})

const loopInsItems = computed(() => {
  if (state.query_type === '0') {
    return insItems.value.filter((f) => f.count)
  } else {
    return insItems.value
  }
})

const insItemsCount = computed(() => {
  return insItems.value.map((f) => f.count || 0).reduce((a, b) => a + b, 0)
})

const onCommand = (ins_name: string) => {
  state.page = 1
  state.ins_name = ins_name
  onFetch()
}

const onRemoveInsName = () => {
  state.ins_name = ''
  onFetch()
}

const onBatchStamp = () => {
  const $grid: VxeGridInstance | undefined = gridRef.value?.getInstance()
  const $stamp = unref(stampRef)
  if ($grid && $stamp) {
    const records = $grid.getCheckboxRecords(true)
    const cans = records.filter((f) => f?.wfRuning?.can_approval)
    if (!cans.length) {
      ElMessage.warning('未勾选可审批行')
      return
    }
    $stamp.open(cans)
  }
}

/**
 * 审批详情
 */
const onNeedViewApp = () => {
  const $grid: VxeGridInstance | undefined = gridRef.value?.getInstance()
  if ($grid) {
    const records = $grid.getCheckboxRecords(true)
    const cans = records.filter((f) => f?.wfRuning?.can_approval)
    if (!cans.length) {
      ElMessage.warning('未勾选可审批行')
      return
    }
    const ids = cans.map((v) => getNotEmpty(v, ['wf_runingid', 'objectId']))
    emitter.emit('onNeedViewApp', {
      list: ids,
      onFetch
    })
  }
}
</script>

<template>
  <TemplateVxeGrid
    ref="gridRef"
    v-model="loading"
    :params="state"
    :toolbar-config="toolbarConfig"
    :ui-form="uiForm"
    :ui-table="uiTable"
    :ui-query="uiQuery"
    :dic-query="dicQuery"
    :dic-table="dicTable"
    :ui-actions="uiActions"
    :wf-design="wfDesign"
    :insert="insert"
    :page-size="state.pageSize"
    :box-shadow="boxShadow"
    :ready="onGridReady"
    @close="emit('close')"
    @fetch="emit('fetch')"
    empty-text="暂无审批消息"
  >
    <template #query_tool>
      <NeedViewStamp ref="stampRef" @fetch="onFetch"></NeedViewStamp>
      <el-radio-group v-model="state.query_type" @change="onFetch" style="margin-left: -5px">
        <el-radio-button label="待审批" value="0" />
        <el-radio-button label="已审批" value="1" />
        <el-radio-button label="我的申请" value="2" />
      </el-radio-group>
      <el-dropdown @command="onCommand" trigger="click">
        <el-button :type="state.ins_name ? 'danger' : 'warning'" plain class="pl5 pr2">
          <span v-if="state.ins_name"
            >{{ getInsItemsName }} [<b class="mx2">{{ getInsItemsCount }}</b
            >]</span
          >
          <span v-else
            >快捷查询 [<b class="mx2">{{ insItemsCount }}</b
            >]</span
          >
          <el-icon class="el-icon--right" v-if="state.ins_name" @click.stop="onRemoveInsName">
            <Close />
          </el-icon>
          <el-icon class="el-icon--right" v-else>
            <ArrowDown />
          </el-icon>
        </el-button>
        <template #dropdown>
          <el-dropdown-menu style="max-height: 50vh">
            <el-dropdown-item
              v-for="(item, index) in loopInsItems"
              :command="item.value"
              :key="index"
            >
              <span>{{ item.label }}</span>
              <span v-if="item.count" class="color-danger">（{{ item.count }}）</span>
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      <el-button
        v-if="state.query_type === '0' && uiActions.some((s) => s.action === 'batch_agree')"
        type="primary"
        :icon="Stamp"
        plain
        @click="onBatchStamp"
        >批量审批
      </el-button>
      <el-button
        v-if="state.query_type === '0' && uiActions.some((s) => s.action === 'batch_open')"
        type="success"
        :icon="List"
        plain
        @click="onNeedViewApp"
      >
        批量打开
      </el-button>
      <el-button :icon="Search" @click="onFetch" :loading="loading">查询</el-button>
    </template>
  </TemplateVxeGrid>
</template>

<style lang="scss">
.need-view {
  background-color: var(--el-bg-color);
  border-radius: 8px 8px 0 0;
  box-sizing: border-box;

  .el-form--inline .el-form-item {
    margin-right: 5px !important;
    margin-bottom: 0 !important;
  }

  .el-form.el-form--inline .el-form-item--small.el-form-item:last-of-type {
    margin-bottom: 0 !important;
  }
}
</style>
